package com.huika.dealontop.utils;

import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;

import com.hk.app.android.lib.encrypt.Base64Encoder;
import com.hk.app.android.lib.encrypt.MD5Security;
import com.hk.app.android.lib.http.VolleyRequestManager;
import com.huika.dealontop.GlobalApp;
import com.nostra13.universalimageloader.utils.StorageUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * 文件操作工具类
 *
 * @author fxl time: 2012-9-24 下午4:31:11
 */
public class FileTool {
    /**
     * 默认的文件保存路径
     */
    private static final String SDCARD_PATH = Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED) ? Environment.getExternalStorageDirectory()
            .getAbsolutePath() : "/mnt/sdcard";
    private static final String defaultFolderName = SDCARD_PATH + "/DealOnTop/savePic";

    public static String getDefaultfoldername() {
        return defaultFolderName;
    }

    /**
     * 从网络上获取图片
     *
     * @param imageUrl 需获取图片的url地址
     * @return byte[]
     * @throws Exception
     */
    public byte[] getImage(String imageUrl) throws Exception {
        InputStream inStream = getImageStream(imageUrl);
        if (inStream != null) {
            return readStream(inStream);
        }
        return null;
    }

    /**
     * 从网络上获取图片
     *
     * @param path 需获取图片的url地址
     * @return InputStream
     * @throws Exception
     */
    public InputStream getImageStream(String path) throws Exception {
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(5 * 1000);
        conn.setRequestMethod("GET");
        if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
            return conn.getInputStream();
        }
        return null;
    }

    /**
     * 把输入流转成字节数组
     *
     * @param inStream
     * @return byte[]
     * @throws Exception
     */
    public static byte[] readStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        outStream.close();
        inStream.close();
        return outStream.toByteArray();
    }

    /**
     * 方法概述：判断文件夹是否存在,如果不存在则创建文件夹
     *
     * @param @param path
     * @return void
     * @throws
     * @description 方法详细描述：
     * @author 刘成伟（wwwlllll@126.com）
     * @Title: FileTool.java
     * @Package com.huika.huixin.utils
     * @date 2014-3-21 下午6:29:33
     */
    public static void isExist(String path) {
        File file = new File(path);
        // 判断文件夹是否存在,如果不存在则创建文件夹
        if (!file.exists()) {
            file.mkdirs();
            try {
                File nomedia = new File(file, ".nomedia");
                nomedia.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取缓冲大小字符串形式
     */
    public static String getCacheSizeString(long size) {
        NumberFormat format = new DecimalFormat("0.00");
        if (size == 0) {
            return "";
        } else if (size < 1024) {
            return size + "B";
        } else {
            double ksize = size / 1024;
            if (ksize < 1024) {
                return format.format(ksize) + "KB";
            } else {
                double msize = ksize / 1024;
                return format.format(msize) + "M";
            }
        }
    }

    /**
     * 获取系统图片缓存大小
     */
    public static long getCacheSize() {
        // volley的缓存目录
        File volleyCacheDir = VolleyRequestManager.getCacheDir();
        // imageLoader的缓存目录
        File cacheDirectory = StorageUtils.getCacheDirectory(GlobalApp.getInstance());
        File cacheFile = GlobalApp.getInstance().getCacheDir();

        File cacheDir = StorageUtils.getOwnCacheDirectory(GlobalApp.getInstance(), GlobalApp.getInstance().getPackageName() + File.separator + "cache/images");
        File cDir = new File("/storage/sdcard0/Android/data/com.huika.hkmallu/cache");
        return getFileSize(volleyCacheDir) + getFileSize(cacheDirectory) + getFileSize(cacheFile) + getFileSize(cacheDir) + getFileSize(cDir);
    }

    /**
     * 获取文件或文件夹大小
     */
    public static long getFileSize(File file) {
        long size = 0;
        if (file.isDirectory()) {
            for (File tempFile : file.listFiles()) {
                size += getFileSize(tempFile);
            }
        } else {
            size += file.length();
        }
        return size;
    }

    /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如：c:/fqf.txt
     * @param newPath String 复制后路径 如：f:/fqf.txt
     * @return boolean
     * @throws Exception
     */
    public static void copyFile(String oldPath, String newPath) throws Exception {
        int byteread = 0;
        File oldfile = new File(oldPath);
        if (oldfile.exists()) { // 文件存在时
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                FileInputStream fis = new FileInputStream(oldPath); // 读入原文件
                bis = new BufferedInputStream(fis);
                FileOutputStream fos = new FileOutputStream(newPath);
                bos = new BufferedOutputStream(fos);
                byte[] buffer = new byte[1024];
                while ((byteread = bis.read(buffer)) != -1) {
                    bos.write(buffer, 0, byteread);
                }
            } finally {
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
            }
        }

    }

    /**
     * 更新图片到相册
     * @param context
     * @param file
     */
    public static void refreshAlbum(Context context, String file){
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(file))));
    }

    /**
     * 删除文件或文件夹
     *
     * @param file
     */
    public static void clear(File file) {
        if (file.exists()) {
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    clear(f);
                    file.delete();
                }
            } else {
                file.delete();
            }
        }
    }

    /**
     * 保存文件
     *
     * @param bm
     * @param fileName
     * @param path     相对SD卡保存路径，如为null或""字符串将默认为 "/EacanNews"
     * @throws IOException
     */
    public static void saveFile(Bitmap bm, String fileName, String path) throws IOException {
        String subForder = FileTool.getDefaultfoldername() + path;
        File foder = new File(subForder);
        if (!foder.exists()) {
            foder.mkdirs();
        }
        File myCaptureFile = new File(subForder, fileName);
        if (!myCaptureFile.exists()) {
            myCaptureFile.createNewFile();
        }
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
        bos.flush();
        bos.close();
    }

    public static String getMD5FromFile(File file) throws IOException {
        FileInputStream in = new FileInputStream(file);
        byte[] bytes = convertStreamToByteArray(in);
        ByteArrayInputStream ins = new ByteArrayInputStream(bytes);
        String fileStr = Base64Encoder.encode(bytes);
        String fileMD5 = MD5Security.getMd5_32(fileStr).toUpperCase();
        return fileMD5;
    }

    private static byte[] convertStreamToByteArray(InputStream is) throws IOException {
        if (is == null) {
            return null;
        }
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            baos.close();
            return baos == null ? null : baos.toByteArray();
        } catch (IOException e) {
            return null;
        } finally {
            if (baos != null)
                baos.close();
            baos = null;
        }
    }

    /**
     * 判断路径是否存在
     * @param path
     * @return
     */
    public static boolean judgeFileExists(String path)
    {
        try
        {
            if (!TextUtils.isEmpty(path))
            {
                File file = new File(path);
                if (file != null && file.exists())
                {
                    return true;
                }
            }
        } catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }

        return false;
    }

    /**
     * 通过图片Uri得到图片path
     */
    public static String getPath(Uri uri, Context mContext)
    {
        String[] proj = {MediaStore.Images.Media.DATA};
        ContentResolver cr = mContext.getContentResolver();

        Cursor cursor = cr.query(uri, proj, null, null, null);
        /***Update By Hush 2015-08-26 可能获取的cursor为空*/
        if (cursor == null)
        {
            return null;
        }
        cursor.moveToFirst();
        int actual_image_column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        String filePath = cursor.getString(actual_image_column_index);
        cursor.close();
        return filePath;
    }


    /**
     * 专为Android4.4设计的从Uri获取文件绝对路径，以前的方法已不好使
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String getPathForKitkat(final Uri uri, Context mContext)
    {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(mContext, uri))
        {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri))
            {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type))
                {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri))
            {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(mContext, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri))
            {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type))
                {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type))
                {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type))
                {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{split[1]};

                return getDataColumn(mContext, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme()))
        {
            return getDataColumn(mContext, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme()))
        {
            return uri.getPath();
        }

        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri)
    {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri)
    {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri)
    {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }


    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs)
    {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {column};

        try
        {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst())
            {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally
        {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

}
